package com.xiaolei.libraryktx

import android.content.Context
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStoreOwner
import androidx.lifecycle.viewModelScope
import com.xiaolei.library.Exts.Ext
import com.xiaolei.library.Medias.Image
import com.xiaolei.library.Medias.Video
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import java.lang.Exception
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.reflect.KClass


/**
 * 快捷对ViewModel进行实例化
 *
 * @param klass    viewmodel的类
 * @param <T>
 * @return 实例
 */
inline fun <reified T : ViewModel> ViewModelStoreOwner.create(klass: KClass<T>): T
{
    return Ext.create(this, klass.java)
}

/**
 * 获取所属的ViewModel实例
 * @param owner 所属于
 * @param klass 获取的ViewModel类型
 */
inline fun <reified T : ViewModel> get(owner: ViewModelStoreOwner, klass: KClass<T>): T?
{
    return try
    {
        ViewModelProvider(owner).get(klass.java)
    } catch (e: Exception)
    {
        e.printStackTrace()
        null
    }
}


/**
 * 启动一个协程,会自动根据生命周期取消任务
 */
inline fun <reified T : ViewModelStoreOwner> T.launchWith(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    noinline block: suspend CoroutineScope.() -> Unit,
): Job?
{
    val viewModel = ViewModelProvider(this).get(ViewModelStoreOwnerViewModel::class.java)
    return viewModel.viewModelScope.launch(context, start, block)
}

class ViewModelStoreOwnerViewModel : ViewModel()


/**
 * 获取视频文件
 */
inline fun <reified T : ViewModelStoreOwner> T.queryMediaVideosWith(
    context: Context,
    coroutineContext: CoroutineContext = IO,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    crossinline onTake: (Video) -> Unit,
)
{
    val viewModel = ViewModelProvider(this).get(ViewModelStoreOwnerViewModel::class.java)
    viewModel.viewModelScope.launch(coroutineContext, start) {
        Ext.queryMediaVideo(context) {
            async(UI) { onTake.invoke(it) }.start()
        }
    }
}

/**
 * 获取视频文件
 */
inline fun <reified T : ViewModelStoreOwner> T.queryMediaVideosWith(
    fragment: Fragment,
    coroutineContext: CoroutineContext = IO,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    crossinline onTake: (Video) -> Unit,
)
{
    val context = fragment.requireContext()
    val viewModel = ViewModelProvider(this).get(ViewModelStoreOwnerViewModel::class.java)
    viewModel.viewModelScope.launch(coroutineContext, start) {
        Ext.queryMediaVideo(context) {
            async(UI) { onTake.invoke(it) }.start()
        }
    }
}

/**
 * 获取图片文件
 */
inline fun <reified T : ViewModelStoreOwner> T.queryMediaImagesWith(
    context: Context,
    coroutineContext: CoroutineContext = IO,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    crossinline onTake: (Image) -> Unit,
)
{
    val viewModel = ViewModelProvider(this).get(ViewModelStoreOwnerViewModel::class.java)
    viewModel.viewModelScope.launch(coroutineContext, start) {
        Ext.queryMediaImage(context) {
            async(UI) { onTake.invoke(it) }.start()
        }
    }
}

/**
 * 获取图片文件
 */
inline fun <reified T : ViewModelStoreOwner> T.queryMediaImagesWith(
    fragment: Fragment,
    coroutineContext: CoroutineContext = IO,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    crossinline onTake: (Image) -> Unit,
)
{
    val context = fragment.requireContext()
    val viewModel = ViewModelProvider(this).get(ViewModelStoreOwnerViewModel::class.java)
    viewModel.viewModelScope.launch(coroutineContext, start) {
        Ext.queryMediaImage(context) {
            async(UI) { onTake.invoke(it) }.start()
        }
    }
}